package office.word.docx4j;

import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.finders.RangeFinder;
import org.docx4j.model.fields.merge.DataFieldName;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;

import javax.xml.bind.JAXBElement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述
 *
 * @author: zhanglu
 * @date: 2023/7/17 14:30
 * @modify: 修改人信息, 修改内容 2023/7/17 14:30
 */
public class BookmarkTest {

    private static boolean DELETE_BOOKMARK = false;

    public static void main(String[] args) throws Exception {
        Map<DataFieldName, String> map = new HashMap<DataFieldName, String>();
        map.put(new DataFieldName("gcmc"), "基建2.0项目子工程");
        map.put(new DataFieldName("jcrqn"), "2023");
        map.put(new DataFieldName("jcrqy"), "07");
        map.put(new DataFieldName("jcrqr"), "17");
        map.put(new DataFieldName("bz01"), "xxx描述备注");
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
                .load(new java.io.File("/Users/zhanglu/Desktop/tmp/docx4j/施工配置达标检查表.docx"));
        MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
        org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document) documentPart
                .getJaxbElement();
        Body body = wmlDocumentEl.getBody();
        replaceBookmarkContents(body.getContent(), map);
        // save the docx...
        wordMLPackage.save(new java.io.File("/Users/zhanglu/Desktop/tmp/word_template2.docx"));
    }

    public static void replaceBookmarkContents(List<Object> paragraphs, Map<DataFieldName, String> data) throws Exception {
        RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
        new TraversalUtil(paragraphs, rt);
        for (CTBookmark bm : rt.getStarts()) {
            // do we have data for this one?
            if (bm.getName()==null) continue;
            String value = data.get(new DataFieldName(bm.getName()));
            if (value==null) continue;
            System.out.println(bm.getName() + ", " + value);
            // Can't just remove the object from the parent,
            // since in the parent, it may be wrapped in a JAXBElement
            List<Object> theList = null;
            if (bm.getParent() instanceof P) {
                theList = ((ContentAccessor)(bm.getParent())).getContent();
            } else {
                continue;
            }
            int rangeStart = -1;
            int rangeEnd=-1;
            int i = 0;
            for (Object ox : theList) {
                Object listEntry = XmlUtils.unwrap(ox);
                if (listEntry.equals(bm)) {
                    if (DELETE_BOOKMARK) {
                        rangeStart=i;
                    } else {
                        rangeStart=i+1;
                    }
                } else if (listEntry instanceof CTMarkupRange) {
                    if ( ((CTMarkupRange)listEntry).getId().equals(bm.getId())) {
                        if (DELETE_BOOKMARK) {
                            rangeEnd=i;
                        } else {
                            rangeEnd= i > rangeStart ? i-1 : i;	 // handle empty bookmark case
                        }
                        break;
                    }
                }
                i++;
            }
            if(rangeStart == rangeEnd){

            }
            R r = (R) theList.get(rangeStart);
            JAXBElement e = (JAXBElement) r.getContent().get(0);
            Text t = (Text) e.getValue();
            t.setValue(value);
        }
    }

}
